Repair a node's export policy rules when it registers - #1186
Open
notsrch wants to merge 1 commit into
Open
Conversation
With autoExportPolicy enabled, the ONTAP NAS drivers write a node's export policy rules only in that node's own ControllerPublishVolume. Nothing adds or corrects a rule afterwards: ReconcileVolumeNodeAccess is a no-op for ontap-nas-economy and ontap-nas, the periodic node-access loop touches only the backend-wide policy, and Kubernetes does not repeat ControllerPublishVolume while a VolumeAttachment exists. A node whose rule goes missing or stale (IP change, out-of-band edit, or the rule wipe in NetApp#1179) fails every mount of the volume until an operator deletes its VolumeAttachments or edits the policy on the array. This change adds the repair path and runs it when a node registers, which is the one event a rebooted or re-addressed node always produces. - Implement ReconcileVolumeNodeAccess for ontap-nas-economy and ontap-nas as an add-only repair of the volume's own per-qtree or per-volume policy for the given nodes. It never removes a rule or changes which policy is assigned, and it skips volumes that are not on a Trident-managed per-volume policy. Economy read-only clones are repaired against their source qtree's policy; ontap-nas clones have no policy of their own and are skipped. - Extract the rule-adding half of the publish path into ensureNodeAccessRulesForPolicy, which takes a node list, so publish and repair share one code path. - In both cores, after AddNode registers the node, a background task collects every volume the node is published to (subordinates resolve to their share source) and repairs each one for every node published to it. Failures are logged and retried at the next registration. Only backends that enforce publications take part. - Remove the classic core's per-volume loop from the synchronous reconcile; it only ever reached no-op driver implementations. The repair is event-driven only. There is no periodic pass, so a rule lost while every node stays up is repaired at the next registration of any node published to that volume. A periodic pass can be layered on the same helpers later. Verified on a live ONTAP cluster: a qtree rule deleted on the array was restored 21 s after the node's Trident pod restarted; the periodic loop alone left it missing. Fixes NetApp#1181. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change description
With
autoExportPolicyenabled, the ONTAP NAS drivers write a node's export policy rules inexactly one place: that node's own
ControllerPublishVolume. Nothing ever adds or corrects arule afterwards.
ReconcileVolumeNodeAccesswas a no-op forontap-nas-economyandontap-nas, the periodic node-access loop only reconciles the backend-wide policy, andKubernetes does not repeat
ControllerPublishVolumewhile a VolumeAttachment exists. So when apublished node's rule went missing or stale (node IP change, out-of-band edit, or the rule wipe
in #1179), that node failed every mount of the volume until an operator deleted its
VolumeAttachments or edited the policy on the array. Issue #1181 describes two production
cases; the second lasted eight days.
This change adds the missing repair path and triggers it on the one event a rebooted or
re-addressed node always produces: registration.
ReconcileVolumeNodeAccessforontap-nas-economyandontap-nasnow addsany missing rules for the given nodes to the volume's own per-qtree or per-volume policy.
It is add-only: it never removes a rule and never changes which policy is assigned. It skips
volumes that are not on a Trident-managed per-volume policy (still on the backend policy,
unpublished, or on a customer-managed policy). Read-only clones on the economy driver share
their source qtree's policy and are repaired against it; on
ontap-nasthey have no policyof their own and are skipped. The recorded
ExportPolicyis trusted rather than re-readfrom ONTAP; a stale record only delays repair to the volume's next publish or unpublish.
ensureNodeAccessRulesForPolicy, which takes a node list, so publish and repair use one codepath. Callers hold the per-policy lock as before.
AddNode. After registering the node, a background task collects everyvolume that node is published to (a subordinate publication resolves to its share-source
volume), and calls the driver repair for each one with every node published to that volume.
A shared RWX volume is therefore repaired for all of its nodes at once, not only for the
node that registered. Failures are logged at warning and retried at the next registration.
Only backends that enforce publications take part.
reconcileNodeAccessOnBackendis removed. It only ever reached no-op driverimplementations, so nothing changes for any driver.
What this does not do. The repair is event-driven only; there is no periodic loop. A rule
that goes missing while every node stays up is not repaired until some node published to that
volume re-registers (Trident node pod restart or node reboot). That is a deliberate first step:
a registration is exactly when a node's IP may have changed, and it avoids one
ExportRuleListper published volume per period. A periodic pass on a slow cadence (for example every 10
minutes) can be layered on the same helpers later if wanted. Until then, "restart the node's
Trident pod" is the documented repair action, and the live test below confirms it also clears
the stuck-unpublish case described in #1184.
Fixes #1181.
Project tracking
Testing
Summary: unit tests for the helper, both drivers, and both cores; the bug was reproduced on a
live ONTAP cluster on a 26.06.0-based build without this change, and the same test passes with
this change applied. Both live runs were done on builds that also carry the #1179 fix from
PR #1183, so the results reflect the combination, not stock 26.06.0.
Unit tests
go build ./...,gofmt -l core storage_drivers/ontapclean.go vetreports onepre-existing warning at
ontap_nas_qtree.go(WaitGroup.Add in goroutine) that is also onmaster.
go test ./core/ ./storage_drivers/ontap/ -count=1green on the branch. The ontap packagehas one pre-existing flaky test (
TestInitializeASANVMe, telemetry goroutine logging afterthe test ends) that fails intermittently on master as well; it is unrelated to this change.
ensureNodeAccessRulesForPolicy(11 cases): multi-node union with de-duplication, CIDRfiltering, missing policy created then populated, comma-format existing rules not
recreated, already-exists tolerated, list error tolerated, create and exists errors
propagated, empty node slice with and without an existing policy.
ReconcileVolumeNodeAccess(12 cases): happy path multi-node, auto exportdisabled, empty nodes, empty internal name, unset or empty policy name, volume still on
the backend policy, customer-managed policy, read-only clone on the source policy,
read-only clone on an unmanaged policy, missing policy recreated, helper error propagated.
ontap-nasdriverReconcileVolumeNodeAccess(11 cases): same matrix; read-only clonesare skipped on this driver.
AddNoderepairs the export rules of the volumes the node ispublished to (both cores, public API).
subordinate publication resolves to the source; source and subordinate produce one repair;
other nodes' publications are not repaired; unregistered node left out; unknown volume
skipped; backend without publish enforcement skipped.
applyNodeAccessRepairs: errors logged and skipped; stops on cancelled context.Live reproduction on v26.06.0 + #1179 fix, without this change (fails)
Environment: 3-node RKE2 cluster, Kubernetes v1.35.4, Trident 26.06.0 plus the #1179 fix from
PR #1183, installed by the operator with
enableConcurrency: true. Oneontap-nas-economybackend on ONTAP 9.17.1P1 (REST),
autoExportPolicy: true, no other volumes on the backend.The #1179 fix touches no repair path, so this run is representative of stock 26.06.0 for the
behaviour under test. Node IPs below are placeholders.
Setup: one RWX PVC (1 Gi), a DaemonSet mounting it so every node holds a publication and a
VolumeAttachment. ONTAP queried and edited over REST from inside the cluster. Before state:
qtree policy and backend policy each 3 rules (
192.0.2.11,192.0.2.12,192.0.2.13), 3publications, 3 VolumeAttachments.
Trigger, from the issue's To Reproduce: delete node-b's rule from the volume's qtree export
policy on the array (
DELETE /api/protocols/nfs/export-policies/{id}/rules/{index}, HTTP 200).Backend policy left intact.
Permission denied(NFSv3 evaluates the policy per request). Other nodes unaffected.FailedMount ... error mounting NFS volume <data-lif>:/<flexvol>/<qtree> ... exit status 32, stuck in ContainerCreating.tridentvolumepublicationslists all 3 nodes;tridentnodesIPs correct.NodeUnpublishVolumefails onstat ...: permission denied(#1184). VolumeAttachment held. Force delete did not help; no forced detach within 10 minutes.Every claim in the issue held: rules are written only by that node's own ControllerPublish for
that volume; the periodic loop and node re-registration do not touch per-qtree policies;
Trident's records stayed correct throughout.
Retest with this change on top of v26.06.0 + #1179 fix (passes)
Same cluster, backend, volume, DaemonSet and query method. Image built from v26.06.0 plus the
#1179 fix plus this branch. Clean state confirmed first: 3 rules in both policies, 3
publications, 3 VolumeAttachments. Controller startup replayed the reconcile for all 10
TridentBackendConfigs with no rule loss.
Comparison:
The
1703945"Ruleset is in use by a volume" warning on each backend reconcile is stillpresent on both builds; that is #1180 and out of scope here.
Checklist
AI assistance
Assisted-by: Claude Fable 5 noreply@anthropic.com